import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/store/modules/user'
import { errorCodeType } from './errorCodeType'
import router from '@/routers'
import { set } from '@vueuse/core'
interface ApiResponse<T = any> {
  code: number
  msg: string
  data: T
}
// 创建axios实例 进行基本参数配置
const request = axios.create({
  // 默认请求地址，根据环境的不同可在.env 文件中进行修改
  baseURL: import.meta.env.VITE_APP_BASE_API, // baseURL, 这里可以根据实际情况修改
  // 设置接口访问超时时间
  timeout: 10000, // request timeout，
  // 跨域时候允许携带凭证
  withCredentials: true,
})

//  request interceptor 接口请求拦截
request.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    /**
     * 用户登录之后获取服务端返回的token,后面每次请求都在请求头中带上token进行JWT校验
     * token 存储在本地储存中（storage）、vuex、pinia
     */
    const token: string = useUserStore().token
    // 自定义请求头
    if (token) {
      config.headers['Authorization'] = token
    }
    return config
  },
  (error: AxiosError) => {
    // 请求错误，这里可以用全局提示框进行提示
    return Promise.reject(error)
  },
)

//  response interceptor 接口响应拦截
request.interceptors.response.use(
  (response: AxiosResponse) => {
    // Add unknown response interceptors here
    if (response.status === 200) {
      return response
    }
    ElMessage({
      message: errorCodeType(response.status),
      type: 'error',
    })
    return response
  },
  // 处理错误
  async (error: AxiosError) => {
    const { response } = error as AxiosError
    if (response && response.status === 401) {
      // 清除用户信息和token
      await useUserStore().logout()
      ElMessage({
        message: errorCodeType(response.status),
        type: 'warning',
      })
      router.push('/login')
      return Promise.reject(response.data)
    } else if (response && response.status === 403) {
      router.push('/403')
      return Promise.reject(response.data)
    } else if (response && response.status === 404) {
      router.push('/404')
      return Promise.reject(response.data)
    }
    ElMessage({
      message: errorCodeType(response.status),
      type: 'error',
    })
  },
)

// 泛型请求函数
export function httpRequest<T = any>(config: AxiosRequestConfig): Promise<T> {
  return new Promise((resolve, reject) => {
    request.request<any, AxiosResponse<ApiResponse>>(config).then((response: AxiosResponse<ApiResponse>) => {
      const data = response.data
      if (!data.code) {
        ElMessage({
          message: data.msg || '请求失败',
          type: 'error',
          duration: 4000,
        })
        reject(data.msg || '请求失败')
      } else {
        resolve(data.data as T)
      }
    })
  })
}
// 封装常用方法
export function get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
  return httpRequest<T>({ url, method: 'get', ...config })
}

export function post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
  return httpRequest<T>({ url, method: 'post', data, ...config })
}

export function put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
  return httpRequest<T>({ url, method: 'put', data, ...config })
}

export function del<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
  return httpRequest<T>({ url, method: 'delete', ...config })
}

export default request
